<?php

namespace App\Services;

use App\Models\ElectricPaymentOrder;
use App\Models\ElectricPlatformAgent;
use Illuminate\Support\Facades\DB;

class PaymentOrderService extends BaseService
{
    /**
     * 2021/3/18--11:25
     * @effect:生成订单
     * @param $request
     * @param $owner |能源运维业主
     * @param $user |用户
     * @return array
     * @author:苏冬冬
     * @QQ:1299273928
     * @method:add_order
     */
    public function add_order($request, $owner, $user): array
    {
        $param = $request->all();

        $openid = $user->openid;//业主信息

        if (empty($openid)) {
            $this->format_error("用户未绑定微信");
        }
        switch ($request->fee_type) {
            case 1:
                if (!isset($owner['electric_id']) || $owner['electric_id'] == 0) {
                    $this->format_error('您尚未绑定电表设备');
                }
                break;
            case 2:
                if (!isset($owner['water_id']) || $owner['water_id'] == 0) {
                    $this->format_error('您尚未绑定水表设备');
                }
                break;
            case 3:
                if (!isset($owner['property_plan_id']) || $owner['property_plan_id'] == 0) {
                    $this->format_error('您尚未匹配物业缴费方案，请联系管理员');
                }
                break;
        }
        $agent = ElectricPlatformAgent::selectRaw('level,split_type,wechat_account,sub_mch_id,rate,rate2,id')->find($owner['fatherId']);
        if ($agent == null) {
            return $this->format_error('代理商不存在');
        }

        $agent = $agent->toArray();
        [$handlingFee, $b1, $split_money, $b2] = $this->getNumbers($request->paymentMoney, $agent, $request->pay_type);
        if ($split_money <= 0) {
            $this->format_error('代理商设置有误');
        }
        $order_arr = [
            'user_id' => $owner['id'],//业主id
            'feeType' => $request->fee_type,//费用类型
            'type' => $request->type,//缴费类型
            'paymentMoney' => $request->paymentMoney,//支付金额
            'pay_type' => $request->pay_type,//支付方式
            'orderNo' => $this->uniqidNumberCode(12),//订单号
            'fatherId' => $owner['fatherId'],//代理商id
            'year' => date('Y'),
            'month' => date('m'),
            'day' => date('d'),
            'split_money' => $split_money,//分账金额
            'handlingFee' => $handlingFee,//手续费
            'after_handling' => $b1,//去掉手续费
            'after_split' => $b2,//再去调分账金额
            'device_type' => $request->device_type,//设备类型
            'openid' => $openid,
            'split_type' => $agent['split_type'],//分账模式
        ];
        if ($request->has("months") && $request->months != '') {
            $order_arr['months'] = $request->months;
        }
        if ($request->haws && $param['is_instead'] == 2) {//他人代缴
            $order_arr['is_instead'] = $param['is_instead'];
        }
        DB::beginTransaction();

        try {
            $res = ElectricPaymentOrder::create($order_arr);
            $options = ['orderId' => $res->id, 'orderNo' => $order_arr['orderNo'], 'agent' => $agent, "owner" => $owner, "openid" => $openid];
            $return_data = $this->pay_do($options);//调起支付
            $order_arr['order_id'] = $res->id;
            $data = [
                'orderArr' => $order_arr,//订单信息
                'return_Data' => $return_data//支付返回信息
            ];
            //发起支付
        } catch (\Exception $e) {
            DB::rollback();
            return $this->format_error($e->getMessage());
        }
        DB::commit();

        return $this->format($data, "创建订单成功");
    }

    /**
     * @notes:支付方式：1️⃣小程序支付；2️⃣公众号支付；3️⃣支付宝支付4️⃣微信H5支付
     * @param $options
     * @return array|null
     * @author Sdd
     */
    public function pay_do($options)
    {
        $orderId = $options['orderId'];//订单id
        $orderNo = $options['orderNo'];//订单号
        $order_fields = 'orderNo,paymentMoney,split_type,pay_type,is_instead,user_id';
        $one_order = ElectricPaymentOrder::selectRaw($order_fields)->find($orderId)->toArray();
        extract($one_order, null);
        /**
         * @var $paymentMoney |支付金额
         * @var $split_type |分账模式
         * @var $pay_type |支付方式：1，小程序支付；2，公众号支付；3，支付宝支付；4，H5支付
         * @var $is_instead |是否为代付:1,否；2，是
         * @var $user_id |业主id
         *
         */

        $owner = $options['owner'];
        $agent = $options['agent'];
        if (empty($one_order)) {
            return $this->format_error('暂无此订单');
        }
        $out_trade_no = $orderNo;//缴费订单号

        $subject = '生活缴费';
        if ($paymentMoney <= 0) {
            return $this->format_error('支付金额不得为0');
        }
//        $total_fee = (float)bcmul($paymentMoney, 100, 2);
        $total_fee=0.01*100;
        switch ($pay_type) {
            case 1://微信小支付
                if ($is_instead === 2) {
                    $arr = session('substitute');
                    $openid = $arr['applets_openid'];//代付人openid
                } else {
                    $openid = $options['openid'];
                }
                $order = [
                    'out_trade_no' => $out_trade_no, //商户订单号
                    'body' => $subject, //商品描述
                    'total_fee' => $total_fee, //订单总金额，单位为分
                    'openid' => $openid, //openid
                ];
                $result = [];
                switch ($split_type) {
                    case 1://无分账
                    case 3://企业付款
                        $result = app("wechat_ordinary_merchant")->miniapp($order);
                        break;
                    case 2://微信分账
                        $order['profit_sharing'] = 'Y';
                        $order['sub_mch_id'] = $agent['sub_mch_id'];
                        $result = app('wechat_server')->miniapp($order);
                        break;
                    default:
                        break;
                }


                return $result;
                break;
            case 2: //微信公众号支付

                break;
            case 3://支付宝支付
                break;
            case 4://微信h5支付
                break;
        }

    }

    /**
     * 唯一数字编码
     * @param integer $length
     * @return string
     */
    public function uniqidNumberCode($length = 10): string
    {
        $time = time() . '';
        if ($length < 10) $length = 10;
        $string = ($time[0] + $time[1]) . substr($time, 2) . rand(0, 9);
        while (strlen($string) < $length) $string .= rand(0, 9);
        return $string;
    }

    /**
     *获取费用数组
     * @param $paymentMoney |支付金额
     * @param $agent |代理商
     * @param $pay_type |支付方式
     * @return array
     * @throws Exception
     * @throws PDOException
     */
    public function getNumbers($paymentMoney, $agent, $pay_type): array
    {
        $handlingFee = 0;
        $b1 = 0;
        $split_money = 0;
        $b2 = 0;
        $fee_config = wx_config('wechat_pay.wechat_app');
        switch ($agent['split_type']) {
            case 1://无分账
                $b1 = $b2 = $paymentMoney;
                break;
            case 2://自动分账
                $rate = $agent['rate'];
                $wechat_discount = sprintf('%.3f', $fee_config['wechat_discount'] / 100);//微信费率
                $handlingFee = bcmul($paymentMoney, $wechat_discount, 2);//手续费计算|(金额*微信费率)
                $b1 = bcsub($paymentMoney, $handlingFee, 2);//去掉手续费 |(金额-手续费)
                if (isset($agent['else_discount']) && $agent['else_discount'] != 0) {
                    $else_handling = bcmul($paymentMoney, $agent['else_discount'], 2);//额外手续费计算，管理员可自行设置
                    $b1 = bcsub($b1, $else_handling, 2);
                }
                $split_money = bcmul($b1, $rate, 2);//分帐金额 |(减去手续费金额*分账比例)
                $b2 = bcsub($b1, $split_money, 2);//分账完余额|(减去手续费金额-分账金额)
                break;
            case 3://手动分账
                $rate = $agent['rate2'];
                $handlingFee = bcmul($paymentMoney, 0.001, 2);//手续费计算|(金额*微信费率)
                if ($pay_type === 3) {//如果支付宝手动分账【转款到支付宝账户，不需要手续费】@todo
                    $handlingFee = 0;
                }

                $b1 = bcsub($paymentMoney, $handlingFee, 2);//去掉手续费 |(金额-手续费)
                $split_money = bcmul($b1, $rate, 2);//分帐金额 |(减去手续费金额*分账比例)
                $b2 = bcsub($b1, $split_money, 2);//分账完余额|(减去手续费金额-分账金额)
                break;
            default:
                break;
        }

        return array($handlingFee, $b1, $split_money, $b2);//再减去分账金额
    }

}
